﻿namespace net.zxteam.ZXLexer.AST
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Text;

	public class Token : IEnumerable<Token>
	{
		public Token(string tokenTypeName, Location token, string name, params Token[] children)
			: this(tokenTypeName, token, name)
		{
			if (children == null) { throw new ArgumentNullException(); }
			if (children.Where(w => w == null).Count() > 0)
			{
				throw new ArgumentException("Bad children array");
			}

			this._text = string.Concat(children.Select(s=>s.Text));
			this._children = children.ToArray();
		}

		public Token(string tokenTypeName, Location token, string name, string text)
			: this(tokenTypeName, token, name)
		{
			if (text == null) { throw new ArgumentNullException(); }

			this._text = text;
			this._children = null;
		}

		private Token(string tokenTypeName, Location token, string name)
		{
			if (tokenTypeName == null) { throw new ArgumentNullException(); }
			if (token == null) { throw new ArgumentNullException(); }

			this._tokenTypeName = tokenTypeName;
			this._token = token;
			this._name = name;
		}

		public override string ToString()
		{
			return string.Format("[{0}] {1}", _tokenTypeName, _text);
		}

		public Location Location { get { return _token; } }
		public string TokenName { get { return _tokenTypeName; } }
		public string Text { get { return _text; } }
		public bool HasChildren { get { return this._children != null && this._children.Length > 0; } }
		public string Name { get { return _name; } }


		private readonly Location _token;
		private readonly string _tokenTypeName;
		private readonly string _text;
		private readonly Token[] _children;
		private readonly string _name;

		public IEnumerator<Token> GetEnumerator() { return _children.OfType<Token>().GetEnumerator(); }

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			if (_children == null) return new Token[0].GetEnumerator();

			return _children.GetEnumerator();
		}
	}
}
